// internal/apps/auth/view/auth_repository.go
package repositories

import (
	"errors"
	"star-go-app/internal/apps/auth/models"
	"star-go-app/pkg/infra/config"
	"star-go-app/pkg/infra/database"
	"time"

	"gorm.io/gorm"
)

// AuthRepository 认证仓储接口
type AuthRepository interface {
	// 用户认证相关
	GetUserByUsername(username string) (*models.User, error)
	GetUserByID(userID uint64) (*models.User, error)

	// Token黑名单相关
	AddTokenToBlacklist(token, tokenType string, userID uint64, reason string, expiresAt time.Time) error
	IsTokenBlacklisted(token string) (bool, error)
	CleanExpiredBlacklistTokens() error

	// 登录会话相关
	CreateLoginSession(session *models.LoginSession) error
	GetLoginSessionByAccessToken(accessToken string) (*models.LoginSession, error)
	GetLoginSessionByRefreshToken(refreshToken string) (*models.LoginSession, error)
	UpdateLoginSessionActivity(sessionID uint64, lastActivity time.Time) error
	DeactivateLoginSession(sessionID uint64) error
	CleanExpiredSessions() error
}

// authRepository 认证仓储实现
type authRepository struct {
	db *gorm.DB
}

// NewAuthRepository 创建认证仓储实例
func NewAuthRepository() AuthRepository {
	return &authRepository{
		db: database.GetDB(),
	}
}

// GetUserByUsername 根据用户名获取用户信息
func (r *authRepository) GetUserByUsername(username string) (*models.User, error) {
	var user models.User
	err := r.db.Preload("Role").Where("username = ? AND status = 1", username).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// GetUserByID 根据用户ID获取用户信息
func (r *authRepository) GetUserByID(userID uint64) (*models.User, error) {
	var user models.User
	err := r.db.Preload("Role").Where("id = ? AND status = 1", userID).First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// AddTokenToBlacklist 添加token到黑名单
func (r *authRepository) AddTokenToBlacklist(token, tokenType string, userID uint64, reason string, expiresAt time.Time) error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	blacklistToken := &models.TokenBlacklist{
		Token:     token,
		TokenType: tokenType,
		UserID:    userID,
		Reason:    reason,
		ExpiresAt: expiresAt,
	}
	return r.db.Create(blacklistToken).Error
}

// IsTokenBlacklisted 检查token是否在黑名单中
func (r *authRepository) IsTokenBlacklisted(token string) (bool, error) {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return false, nil // 功能未启用，始终返回false
	}

	var count int64
	err := r.db.Model(&models.TokenBlacklist{}).Where("token = ? AND expires_at > ?", token, time.Now()).Count(&count).Error
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// CleanExpiredBlacklistTokens 清理过期的黑名单token
func (r *authRepository) CleanExpiredBlacklistTokens() error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	return r.db.Where("expires_at <= ?", time.Now()).Delete(&models.TokenBlacklist{}).Error
}

// CreateLoginSession 创建登录会话
func (r *authRepository) CreateLoginSession(session *models.LoginSession) error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	return r.db.Create(session).Error
}

// GetLoginSessionByAccessToken 根据访问令牌获取登录会话
func (r *authRepository) GetLoginSessionByAccessToken(accessToken string) (*models.LoginSession, error) {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil, errors.New("高级认证功能未启用")
	}

	var session models.LoginSession
	err := r.db.Where("access_token = ? AND is_active = ? AND expires_at > ?", accessToken, true, time.Now()).First(&session).Error
	if err != nil {
		return nil, err
	}
	return &session, nil
}

// GetLoginSessionByRefreshToken 根据刷新令牌获取登录会话
func (r *authRepository) GetLoginSessionByRefreshToken(refreshToken string) (*models.LoginSession, error) {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil, errors.New("高级认证功能未启用")
	}

	var session models.LoginSession
	err := r.db.Where("refresh_token = ? AND is_active = ? AND expires_at > ?", refreshToken, true, time.Now()).First(&session).Error
	if err != nil {
		return nil, err
	}
	return &session, nil
}

// UpdateLoginSessionActivity 更新登录会话活动时间
func (r *authRepository) UpdateLoginSessionActivity(sessionID uint64, lastActivity time.Time) error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	return r.db.Model(&models.LoginSession{}).Where("id = ?", sessionID).Update("last_activity", lastActivity).Error
}

// DeactivateLoginSession 停用登录会话
func (r *authRepository) DeactivateLoginSession(sessionID uint64) error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	return r.db.Model(&models.LoginSession{}).Where("id = ?", sessionID).Update("is_active", false).Error
}

// CleanExpiredSessions 清理过期的会话
func (r *authRepository) CleanExpiredSessions() error {
	// 检查是否启用高级认证功能
	if !config.GetConfig().JWT.EnableAdvancedAuth {
		return nil // 功能未启用，直接返回成功
	}

	return r.db.Model(&models.LoginSession{}).Where("expires_at <= ?", time.Now()).Update("is_active", false).Error
}
